import { inBrowser } from 'vitepress';
import type { Route } from 'vitepress';

type SidebarItem = {
  text: string;
  link?: string;
  children?: Array<SidebarItem>;
};

type SidebarConfig = Array<SidebarItem>;

type Sidebar =
  | {
      [key: string]: SidebarConfig;
    }
  | false
  | 'auto';

export const hashRE = /#.*$/;
export const extRE = /(index)?\.(md|html)$/;
export const endingSlashRE = /\/$/;
export const outboundRE = /^[a-z]+:/i;

export const getSidebarConfig = (sidebar: Sidebar, path: string) => {
  if (sidebar === false || Array.isArray(sidebar) || sidebar === 'auto') {
    return [];
  }
  path = ensureStartingSlash(path);
  for (const dir in sidebar) {
    // make sure the multi sidebar key starts with slash too
    if (path.startsWith(ensureStartingSlash(`${dir}`))) {
      return sidebar[dir];
    }
  }
  return [];
};

export const getFlatSideBarLinks = (sidebar: SidebarConfig) => {
  return sidebar.reduce((links: SidebarConfig, item) => {
    if (item.link) {
      links.push({ text: item.text, link: removeExtention(item.link) });
    }
    if (isSideBarGroup(item)) {
      links = [...links, ...getFlatSideBarLinks(item.children || [])];
    }
    return links;
  }, []);
};

export const isArray = (value: any): value is any[] => {
  return Array.isArray(value);
};

export const removeExtention = (path: string): string => {
  return path.replace(/(index)?(\.(md|html))?$/, '') || '/';
};

export const isSideBarGroup = (item: SidebarItem) => {
  return item.children !== undefined;
};

export const isActive = (route: Route, path?: string): boolean => {
  if (path === undefined) {
    return false;
  }

  const routePath = normalize(`/${route.data.relativePath}`);
  const pagePath = normalize(path);

  return routePath === pagePath;
};

export const normalize = (path: string): string => {
  return decodeURI(path).replace(hashRE, '').replace(extRE, '');
};

export const ensureStartingSlash = (path: string): string => {
  return /^\//.test(path) ? path : `/${path}`;
};

export const createGitHubUrl = (
  docsRepo: string,
  docsDir: string,
  docsBranch: string,
  path: string,
  folder = 'examples/',
  ext = '.vue',
) => {
  const base = isExternal(docsRepo) ? docsRepo : `https://github.com/${docsRepo}`;
  return `${base.replace(endingSlashRE, '')}/edit/${docsBranch}/${
    docsDir ? `${docsDir.replace(endingSlashRE, '')}/` : ''
  }${folder || ''}${path}${ext || ''}`;
};

export const isExternal = (path: string): boolean => {
  return outboundRE.test(path);
};
